package com.custom.custapi.mapper;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.custom.custapi.handler.SuperBaseMapperHandler;
import com.custom.custapi.id.SuperIDGenerate;
import com.custom.custapi.pojo.SuperBaseEntity;
import com.custom.custapi.pojo.SuperBaseFilter;
import com.custom.custapi.pojo.SuperBasePager;
import lombok.extern.log4j.Log4j2;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @author zl
 * @version 1.0
 * @description 超级Mapper实现类
 * @date 2025/1/1 1:1
 */
@Log4j2
@Component
public class SuperMapperImpl implements SuperMapper {
    @Resource
    private SuperIDGenerate idGenerate;
    private SuperBaseMapperHandler superHandler;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        superHandler = new SuperBaseMapperHandler(applicationContext, DEFAULT_BATCH_SIZE);
    }

    public <T extends SuperBaseEntity, R, F extends SuperBaseFilter> SuperBasePager<R> selectPage(F filter, Class<T> tClass) {
        SuperBaseMapper<T> mapper = superHandler.getMapper(tClass);
        IPage<R> req = new Page<>(filter.getPageNum(), filter.getPageSize());
        IPage<R> result = mapper.custPage(req, filter);
        return new SuperBasePager<R>().to(result);
    }

    @Override
    public <T extends SuperBaseEntity> T selectById(Serializable id, Class<T> tClass) {
        return superHandler.getMapper(tClass).selectById(id);
    }

    @Override
    public <T extends SuperBaseEntity> List<T> selectBatchIds(Collection<? extends Serializable> idList, Class<T> tClass) {
        return superHandler.getMapper(tClass).selectBatchIds(idList);
    }

    @Override
    public <T extends SuperBaseEntity> T selectOne(Wrapper<T> queryWrapper) {
        return superHandler.getMapper(queryWrapper).selectOne(queryWrapper);
    }

    @Override
    public <T extends SuperBaseEntity> List<T> selectAll(Class<T> tClass) {
        SuperBaseMapper<T> mapper = superHandler.getMapper(tClass);
        return mapper.selectList(null);
    }

    @Override
    public <T extends SuperBaseEntity> List<T> selectList(Wrapper<T> queryWrapper) {
        return superHandler.getMapper(queryWrapper).selectList(queryWrapper);
    }

    @Override
    public <T extends SuperBaseEntity> List<Map<String, Object>> selectMaps(Wrapper<T> queryWrapper) {
        return superHandler.getMapper(queryWrapper).selectMaps(queryWrapper);
    }

    @Override
    public <T extends SuperBaseEntity> Long selectCount(Wrapper<T> queryWrapper) {
        return superHandler.getMapper(queryWrapper).selectCount(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public <T extends SuperBaseEntity> int insert(@Param(Constants.ENTITY) T entity) {
        return superHandler.getMapper(entity).insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public <T extends SuperBaseEntity> void insertList(Collection<T> dataList) {
        if (CollectionUtil.isEmpty(dataList)) {
            return;
        }
        SuperBaseMapper<T> mapper = superHandler.getMapper(dataList);
        List<List<T>> lists = superHandler.countStep(dataList);
        for (List<T> list : lists) {
            mapper.insertBatch(list);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public <T extends SuperBaseEntity> int update(T entity, Wrapper<T> updateWrapper) {
        return superHandler.getMapper(entity).update(entity, updateWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public <T extends SuperBaseEntity> int updateById(T entity) {
        return superHandler.getMapper(entity).updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public <T extends SuperBaseEntity> void updateList(Collection<T> dataList) {
        if (CollectionUtil.isEmpty(dataList)) {
            return;
        }
        SuperBaseMapper<T> mapper = superHandler.getMapper(dataList);
        List<List<T>> lists = superHandler.countStep(dataList);
        for (List<T> list : lists) {
            mapper.updateBatch(list);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public <T extends SuperBaseEntity> int delete(Wrapper<T> queryWrapper) {
        return superHandler.getMapper(queryWrapper).delete(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public <T extends SuperBaseEntity> int deleteById(T entity) {
        return superHandler.getMapper(entity).deleteById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public <T extends SuperBaseEntity> int deleteById(Serializable id, Class<T> tClass) {
        return superHandler.getMapper(tClass).deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public <T extends SuperBaseEntity> int deleteBatchIds(Collection<?> idList, Class<T> tClass) {
        return superHandler.getMapper(tClass).deleteBatchIds(idList);
    }

}
